<div id="innerContainer">
    <div class="row">
        <div class="form-body">
            <form id="filterBasicForm">
                <div class="form-title" data-trans="port_filter"></div>
                <div class="content">
                    <div class="row form-group">
                        <label class="span4 side-right" data-trans="port_filter_enabled"></label>
                        <div class="span8">
                            <div class="row">
                                <div class="col-xs-4">
                                    <input type="radio" name="filterGrp" id="filterEnable" data-bind="checked: portFilterEnable" value="1" />
                                    <label for="filterEnable" data-trans="enable"></label>

                                    <input type="radio" name="filterGrp" id="filterDisable" data-bind="checked: portFilterEnable" value="0" />
                                    <label for="filterDisable" data-trans="disable"></label>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="row form-group" data-bind="visible: portFilterEnable() == '1' ">
                        <label class="span4 side-right" data-trans="default_policy"></label>
                        <div class="span8">
                            <div class="row">
                                <div class="col-xs-4">
                                    <input type="radio" name="defaultPolicyGrp" id="defaultPolicyAccept" data-bind="checked: defaultPolicy, event: {click: policyChangeHandler}" value="0" />
                                    <label for="defaultPolicyAccept" data-trans="accepted"></label>

                                    <input type="radio" name="defaultPolicyGrp" id="defaultPolicyDrop" data-bind="checked: defaultPolicy, event: {click: policyChangeHandler}" value="1" />
                                    <label for="defaultPolicyDrop" data-trans="dropped"></label>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="form-buttons">
                    <input type="submit" class="btn-1 btn-primary" data-trans="apply" />
                </div>
                <div class="form-note">
                    <div class="notes-title">&nbsp;</div>
                    <ul class="notes-content">
                        <li data-trans="default_policy_note"></li>
                        <li data-trans="default_policy_note_filter"></li>
                    </ul>
                </div>
            </form>
            <div data-bind="visible: oriPortFilterEnable() == '1' && portFilterEnable() == '1' ">
                <form id="portFilterForm">
                    <div class="form-title">
                        <div data-trans="port_filter_setting"></div>
                    </div>
                    <div class="content">
                        <div class="row form-group" data-bind="visible: ipv6Support">
                            <label class="span4 side-right" data-trans="filter_ip_setting"></label>
                            <div class="span8">
                                <div class="row">
                                    <div class="col-xs-4">
                                        <input type="radio" name="ipTypeGrp" id="filterIpv4" data-bind="checked: ipType, event: {click: ipTypeChangeHandler}" value="ipv4" />
                                        <label for="filterIpv4" data-trans="filter_ipv4"></label>

                                        <input type="radio" name="ipTypeGrp" id="filterIpv6" data-bind="checked: ipType, event: {click: ipTypeChangeHandler}" value="ipv6" />
                                        <label for="filterIpv6" data-trans="filter_ipv6"></label>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="row form-group">
                            <label class="span4 side-right" for="txtMacAddress" data-trans="mac_address"></label>
                            <div class="span8">
                                <div class="row">
                                    <div class="col-xs-8">
                                        <input type="text" name="txtMacAddress" id="txtMacAddress" data-bind="value: macAddress" maxlength="17" class="form-control" />
                                        <label class="col-xs-4" data-trans="macExam" id="macExamLabel"></label>
                                        <div id="macErrorDiv"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div data-bind="visible: ipType() =='ipv4'">
                            <div class="row form-group">
                                <label class="span4 side-right" for="txtSourceIpAddress" data-trans="source_ip_address"></label>
                                <div class="span8">
                                    <input type="text" name="txtSourceIpAddress" id="txtSourceIpAddress" data-bind="value: sourceIpAddress" maxlength="15" class="form-control" />
                                </div>
                            </div>
                            <div class="row form-group">
                                <label class="span4 side-right" for="txtDestIpAddress" data-trans="dest_ip_address"></label>
                                <div class="span8">
                                    <input type="text" name="txtDestIpAddress" id="txtDestIpAddress" data-bind="value: destIpAddress" maxlength="15" class="form-control" />
                                </div>
                            </div>
                        </div>
                        <div data-bind="visible: ipType() =='ipv6'">
                            <div class="row form-group">
                                <label class="span4 side-right" for="txtSourceIpv6Address" data-trans="source_ipv6_address"></label>
                                <div class="span8">
                                    <input type="text" name="txtSourceIpv6Address" id="txtSourceIpv6Address" data-bind="value: sourceIpv6Address" class="form-control" />
                                </div>
                            </div>
                            <div class="row form-group">
                                <label class="span4 side-right" for="txtDestIpv6Address" data-trans="dest_ipv6_address"></label>
                                <div class="span8">
                                    <input type="text" name="txtDestIpv6Address" id="txtDestIpv6Address" data-bind="value: destIpv6Address" class="form-control" />
                                </div>
                            </div>
                        </div>
                        <div class="row form-group">
                            <label class="span4 side-right" for="protocol" data-trans="protocol"></label>
                            <div class="span8">
                                <select id="protocol" data-transid="protocol" data-bind="options: modes, value: selectedMode, optionsText: transOption('protocol'), optionsValue: 'value', event:{ change: protocolChangeHandler}" class="form-control"></select>
                            </div>
                        </div>
                        <!--根据protocol显示或隐藏-->
                        <div id="portRangeArea" data-bind="visible: selectedMode() != 'ICMP' && selectedMode() != 'None' ">
                            <div class="row form-group">
                                <label class="span4 side-right" for="txtSourcePortStart" data-trans='source_port_range'></label>
                                <div class="span8 form-inline">
                                    <input id='txtSourcePortStart' name="txtSourcePortStart" type="text" data-bind="value: sourcePortStart" class="required rangeInput form-control" maxlength="5" /> -
                                    <input id='txtSourcePortEnd' name="txtSourcePortEnd" type="text" data-bind="value: sourcePortEnd" class="required rangeInput form-control" maxlength="5" />
                                    <label class="col-xs-4" id='sourceRangeLabel'>(1~65535)</label>

                                    <div id="sourcePortErrorDiv"></div>
                                </div>
                            </div>
                            <div class="row form-group">
                                <label class="span4 side-right" for="txtDestPortStart" data-trans='dest_port_range'></label>
                                <div class="span8 form-inline">

                                    <input id='txtDestPortStart' name="txtDestPortStart" type="text" data-bind="value: destPortStart" class="required rangeInput form-control" maxlength="5" /> -
                                    <input id='txtDestPortEnd' name="txtDestPortEnd" type="text" data-bind="value: destPortEnd" class="required rangeInput form-control" maxlength="5" />

                                    <label class="col-xs-4" id='destRangeLabel'>(1~65535)</label>
                                    <div id="destPortErrorDiv"></div>
                                </div>
                            </div>

                            <div class="row form-group">
                                <label class="span4 side-right" data-trans="port_filter_action"></label>
                                <div class="span8">
                                    <div class="row">
                                        <div class="col-xs-4">
                                            <input type="radio" name="portFilterActionGrp" id="portFilterAccept" data-bind="checked: portFilterAction" value="Accept" />
                                            <label for="portFilterAccept" data-trans="filter_accept"></label>

                                            <input type="radio" name="portFilterActionGrp" id="portFilterDrop" data-bind="checked: portFilterAction" value="Drop" />
                                            <label for="portFilterDrop" data-trans="filter_drop"></label>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="row form-group">
                                <label class="span4 side-right" for="txtComment" data-trans="comment"></label>
                                <div class="span8">
                                    <input type="text" name="txtComment" id="txtComment" data-bind="value: comment" class="required form-control" maxlength="32" />
                                </div>
                            </div>
                        </div>
                        <div class="form-buttons">
                            <input type="submit" class="btn-1 btn-primary" data-trans="apply" />
                        </div>
                        <div class="form-note">
                            <div class="notes-title">&nbsp;</div>
                            <ul class="notes-content">
                                <li data-trans="port_filter_note_mac_address"></li>
                                <li data-trans="port_filter_note_source_ip_address"></li>
                                <li data-trans="port_filter_note_dest_ip_address"></li>
                                <li data-trans="port_filter_note_protocol"></li>
                                <li data-trans="port_filter_note_source_port_range"></li>
                                <li data-trans="port_filter_note_dest_port_range"></li>
                                <li data-trans="port_filter_note_action"></li>
                                <li data-trans="port_filter_note_comment"></li>
                                <li data-trans="port_filter_note_info"></li>
                                <li data-trans="rule_max_note_v4v6" data-bind="visible: ipv6Support"></li>
                                <li data-trans="rule_max_note" data-bind="visible: !ipv6Support()"></li>
                            </ul>
                        </div>
                </form>
                <form id="portFilterListForm">
                    <div class="form-title">
                        <div data-trans="port_filter_list"></div>
                    </div>
                    <div class="content">
                        <div>
                            <div id="portFilters" class="fixTableScroll" data-bind="simpleGrid: gridTemplate"></div>
                        </div>
                    </div>

                    <div class="form-buttons">
                        <input type="submit" class="btn-1 btn-primary" data-trans="delete" data-bind="enable: gridTemplate.checkedCount() > 0" />
                    </div>

                    <!-- ko if: oriDefaultPolicy() == '0' -->
                    <div class="form-note">
                        <div class="notes-title">&nbsp;</div>
                        <ul class="notes-content">
                            <li data-trans="filter_accept_note"></li>
                        </ul>
                    </div>
                    <!-- /ko -->
                    <!-- ko if: oriDefaultPolicy() == '1' -->
                    <div class="form-note">
                        <div class="notes-title">&nbsp;</div>
                        <ul class="notes-content">
                            <li data-trans="filter_drop_note"></li>
                        </ul>
                    </div>
                    <!-- /ko -->
                </form>
                </div>
            </div>
        </div>
    </div>

    <script>
        $(function() {
            var service = window._service;
            var config = service.config;

            var PROTOCOL = {
                ICMP: 'ICMP',
                NONE: 'None'
            };

            var protocolModes = _.map(config.FILTER_PROTOCOL_MODES, function(item) {
                return new Option(item.name, item.value);
            });

            var columnsTmpl = [{
                columnType: "checkbox",
                rowText: "index",
                width: "4%"
            }, {
                headerTextTrans: "mac_address",
                rowText: "macAddress",
                width: "12%"
            }, {
                headerTextTrans: "ip_type",
                rowText: "ipType",
                width: "5%",
                display: config.IPV6_SUPPORT
            }, {
                headerTextTrans: "source_ip_address",
                rowText: "sourceIpAddress",
                width: "12%"
            }, {
                headerTextTrans: "dest_ip_address",
                rowText: "destIpAddress",
                width: "12%"
            }, {
                headerTextTrans: "protocol",
                rowText: "protocol",
                width: "12%",
                needTrans: true
            }, {
                headerTextTrans: "source_port_range",
                rowText: "sourcePortRange",
                width: "12%"
            }, {
                headerTextTrans: "dest_port_range",
                rowText: "destPortRange",
                width: "12%"
            }, {
                headerTextTrans: "port_filter_action",
                rowText: "action",
                width: "12%",
                needTrans: true
            }, {
                headerTextTrans: "comment",
                rowText: "comment",
                width: "12%"
            }];

            /**
             * prot_filter VM
             * @class PortFilterVM
             */
            function PortFilterVM() {
                var self = this;
                var info = getPortFilter();

                self.portFilterEnable = ko.observable(info.portFilterEnable);
                self.oriPortFilterEnable = ko.observable(info.portFilterEnable);
                self.defaultPolicy = ko.observable(info.defaultPolicy);
                self.oriDefaultPolicy = ko.observable(info.defaultPolicy);

                self.portFilterAction = ko.observable('');
                self.macAddress = ko.observable('');
                self.destIpAddress = ko.observable('');
                self.sourceIpAddress = ko.observable('');
                self.sourceIpv6Address = ko.observable('');
                self.destIpv6Address = ko.observable('');
                self.destPortStart = ko.observable('');
                self.destPortEnd = ko.observable('');
                self.sourcePortStart = ko.observable('');
                self.sourcePortEnd = ko.observable('');
                self.modes = ko.observableArray(protocolModes);
                self.selectedMode = ko.observable('5');
                self.comment = ko.observable('');
                self.ipv6Support = ko.observable(config.IPV6_SUPPORT);

                self.ipType = ko.observable('ipv4');

                self.rules = ko.observableArray(info.portFilterRules);

                /**
                 * default policy change handler
                 * @event policyChangeHandler
                 */
                self.policyChangeHandler = function() {
                    var filterAction = self.defaultPolicy() == "1" ? "Accept" : "Drop";
                    self.portFilterAction(filterAction);
                    return true;
                };
                /**
                 * 创建列表模板
                 * @event gridTemplate
                 */
                self.gridTemplate = new ko.simpleGrid.viewModel({
                    data: self.rules(),
                    idName: "index",
                    columns: columnsTmpl,
                    tmplType: 'list',
                    pageSize: 20
                });

                /**
                 * 设定,新增,删除回调函数
                 * @method callback
                 */
                self.callback = function(result) {
                    if (result.result == "success") {
                        self.clear();
                        init(self);
                        successOverlay();
                    } else {
                        errorOverlay();
                    }
                };

                /**
                 * 清空添加规则输入
                 * @method clear
                 */
                self.clear = function() {
                    self.macAddress('');
                    self.destIpAddress('');
                    self.destIpv6Address('');
                    self.sourceIpAddress('');
                    self.sourceIpv6Address('');
                    self.destPortStart('0');
                    self.destPortEnd('0');
                    self.sourcePortStart('0');
                    self.sourcePortEnd('0');
                    self.selectedMode('None');
                    self.comment('');
                    clearValidateMsg();
                };

                /**
                 * 设定过滤基本信息
                 * @method enableVirtualServer
                 */
                self.setPortFilterBasic = function() {
                    showLoading();
                    var params = {};
                    params.portFilterEnable = self.portFilterEnable();
                    params.defaultPolicy = self.defaultPolicy();
                    service.setPortFilterBasic(params, self.callback);
                };

                /**
                 * 保存规则
                 * @method save
                 */
                self.save = function() {
                    self.macAddress(self.macAddress().replace(/\s+/g, ''));
                    self.destIpv6Address(self.destIpv6Address().replace(/\s+/g, ''));
                    self.sourceIpv6Address(self.sourceIpv6Address().replace(/\s+/g, ''));
                    self.destIpAddress(self.destIpAddress().replace(/\s+/g, ''));
                    self.sourceIpAddress(self.sourceIpAddress().replace(/\s+/g, ''));
                    if (self.ipv6Support()) {
                        var typeInfo = self.ipType() == "ipv4" ? "IPv4" : "IPv6";
                        var oldRules = _.filter(self.rules(), function(ruleItem) {
                            return ruleItem.ipType == typeInfo;
                        });

                        if (oldRules.length >= config.portForwardMax) {
                            showAlert("rules_max_v4v6", null, [typeInfo, config.portForwardMax]);
                            return;
                        }

                        if (self.checkExist()) {
                            showAlert("rule_exist_v4v6", null, [typeInfo]);
                            return;
                        }

                    } else {
                        if (self.rules().length >= config.portForwardMax) {
                            showAlert("rules_max", null, [config.portForwardMax]);
                            return;
                        }

                        if (self.checkExist()) {
                            showAlert("rule_exist");
                            return;
                        }
                    }
                    showConfirm("", "confirm_data_effect", function() {
                        showLoading();
                        var params = {};
                        params.macAddress = self.macAddress();

                        if (self.ipv6Support() && self.ipType() == 'ipv6') {
                            params.destIpAddress = self.destIpv6Address();
                            params.sourceIpAddress = self.sourceIpv6Address();
                        } else {
                            params.destIpAddress = self.destIpAddress();
                            params.sourceIpAddress = self.sourceIpAddress();
                        }

                        params.destPortStart = self.destPortStart();
                        params.destPortEnd = self.destPortEnd();
                        params.sourcePortStart = self.sourcePortStart();
                        params.sourcePortEnd = self.sourcePortEnd();
                        params.action = self.portFilterAction();
                        params.protocol = self.selectedMode();
                        params.comment = self.comment();
                        params.ipType = self.ipType();
                        service.setPortFilter(params, self.callback);
                    });
                };

                /**
                 * 检查新增规则是否已经存在
                 * @method checkExist
                 */
                self.checkExist = function() {
                    self.macAddress(self.macAddress().toUpperCase());
                    var newIpType = self.ipType().toUpperCase();
                    var newRule = {
                        macAddress: self.macAddress(),
                        destIpAddress: newIpType == "IPV4" ? self.destIpAddress() : self.destIpv6Address(),
                        sourceIpAddress: newIpType == "IPV4" ? self.sourceIpAddress() : self.sourceIpv6Address(),
                        destPortRange: self.destPortStart() == '0' ? '' : self.destPortStart() + ' - ' + self.destPortEnd(),
                        sourcePortRange: self.sourcePortStart() == '0' ? '' : self.sourcePortStart() + ' - ' + self.sourcePortEnd(),
                        action: self.portFilterAction() == "Drop" ? "filter_drop" : "filter_accept",
                        protocol: transProtocolValue(self.selectedMode()),
                        ipType: newIpType
                    };

                    var oldRule;
                    var rules = self.rules();
                    for (var i = 0; i < rules.length; i++) {
                        oldRule = {
                            macAddress: rules[i].macAddress,
                            destIpAddress: rules[i].destIpAddress,
                            sourceIpAddress: rules[i].sourceIpAddress,
                            destPortRange: rules[i].destPortRange,
                            sourcePortRange: rules[i].sourcePortRange,
                            action: rules[i].action,
                            protocol: rules[i].protocol,
                            ipType: rules[i].ipType.toUpperCase()
                        };

                        if (_.isEqual(newRule, oldRule)) {
                            return true;
                        }
                    }
                    return false;
                };

                /**
                 * 删除规则
                 * @method deleteFilterRules
                 */
                self.deleteFilterRules = function() {
                    var ids = self.gridTemplate.selectedIds();
                    if (ids.length == 0) {
                        showAlert("no_data_selected");
                        return;
                    }

                    showConfirm("", "confirm_data_effect", function() {
                        showLoading('deleting');
                        var params = {};
                        params.indexs = ids;
                        service.deleteFilterRules(params, self.callback);
                    });
                };

                /**
                 * 协议变化事件监听
                 * @event protocolChangeHandler
                 */
                self.protocolChangeHandler = function() {
                    if (self.selectedMode() == PROTOCOL.ICMP || self.selectedMode() == PROTOCOL.NONE) {
                        self.destPortStart('0');
                        self.destPortEnd('0');
                        self.sourcePortStart('0');
                        self.sourcePortEnd('0');
                        clearValidateMsg('#portRangeArea');
                    } else {
                        self.destPortStart('1');
                        self.destPortEnd('65535');
                        self.sourcePortStart('1');
                        self.sourcePortEnd('65535');
                    }
                    return true;
                };

                /**
                 * ip类型变化事件监听
                 * @event ipTypeChangeHandler
                 */
                self.ipTypeChangeHandler = function() {
                    clearValidateMsg();
                    return true;
                };

                //init to call
                self.policyChangeHandler();
            }

            /**
             * 获取port filter信息
             * @method getPortFilter
             */
            function getPortFilter() {
                return service.getPortFilter();
            }

            /**
             * 初始化port filter view model
             * @method init
             */
            function init(viewModel) {
                var vm;
                if (viewModel) {
                    vm = viewModel;
                    var info = getPortFilter();
                    vm.portFilterEnable(info.portFilterEnable);
                    vm.oriPortFilterEnable(info.portFilterEnable);
                    vm.defaultPolicy(info.defaultPolicy);
                    vm.oriDefaultPolicy(info.defaultPolicy);
                    vm.rules(info.portFilterRules);
                    vm.gridTemplate.clearAllChecked();
                    vm.gridTemplate.data(info.portFilterRules);
                    refreshTableHeight();
                    $('#portFilters').find('tbody').translate();
                    renderCheckbox();
                    $('.notes-content').translate();
                    return;
                }

                vm = new PortFilterVM();
                var container = $('#container');
                ko.cleanNode(container[0]);
                ko.applyBindings(vm, container[0]);

                fixTableHeight();

                $('#filterBasicForm').validate({
                    submitHandler: function() {
                        showConfirm("", "confirm_data_effect", function() {
                            vm.setPortFilterBasic();
                        });
                    }
                });

                $('#portFilterListForm').validate({
                    submitHandler: function() {
                        vm.deleteFilterRules();
                    }
                });

                $('#portFilterForm').validate({
                    submitHandler: function() {
                        vm.save();
                    },
                    rules: {
                        txtMacAddress: {
                            filter_optional: true,
                            mac_check: true
                        },
                        txtDestIpAddress: {
                            ip_check: true
                        },
                        txtSourceIpAddress: {
                            ip_check: true
                        },
                        txtSourceIpv6Address: {
                            ipv6: true
                        },
                        txtDestIpv6Address: {
                            ipv6: true
                        },
                        txtDestPortStart: {
                            digits: true,
                            range: [1, 65535],
                            portCompare: "#txtDestPortEnd"
                        },
                        txtDestPortEnd: {
                            digits: true,
                            range: [1, 65535],
                            portCompare: "#txtDestPortStart"
                        },
                        txtSourcePortStart: {
                            digits: true,
                            range: [1, 65535],
                            portCompare: "#txtSourcePortEnd"
                        },
                        txtSourcePortEnd: {
                            digits: true,
                            range: [1, 65535],
                            portCompare: "#txtSourcePortStart"
                        },

                        txtComment: {
                            comment_check: true
                        }
                    },
                    groups: {
                        destPort: "txtDestPortStart txtDestPortEnd",
                        sourcePort: "txtSourcePortStart txtSourcePortEnd"
                    },
                    errorPlacement: function(error, element) {
                        if (element.attr("name") == "txtMacAddress") {
                            error.appendTo("#macErrorDiv");
                        } else if (element.attr("name") == "txtDestPortStart" || element.attr("name") == "txtDestPortEnd") {
                            error.appendTo("#destPortErrorDiv");
                        } else if (element.attr("name") == "txtSourcePortStart" || element.attr("name") == "txtSourcePortEnd") {
                            error.appendTo("#sourcePortErrorDiv");
                        } else
                            error.insertAfter(element);
                    }
                });
            }

            $.validator.addMethod("filter_optional", function(value, element, param) {
                var result = _.any(['#txtMacAddress', '#txtDestIpAddress', '#txtSourceIpAddress', '#txtSourceIpv6Address', '#txtDestIpv6Address'],
                    function(item) {
                        var tmp = $(item).val().replace(/\s+/g, '');
                        return $(item + ':visible').length > 0 && tmp != '';
                    }
                );

                var portResult = _.any(['#txtDestPortStart', '#txtDestPortEnd', '#txtSourcePortStart', '#txtSourcePortEnd'],
                    function(item) {
                        return $(item).val() != '0';
                    }
                );

                return result || portResult;
            });

            init();
            $('#innerContainer').translate();
        });
    </script>